<script setup lang="ts">
import Editor, { RowFlex,ControlType,ElementType,splitText,TextDecorationStyle,TitleLevel,ListType,ListStyle,BlockType} from '@hufe921/canvas-editor';
import type {IElement,IBlock} from '@hufe921/canvas-editor'
import './editor.scss';
import {onMounted, onUnmounted, ref} from 'vue';
import MenuBar from './MenuBar.vue';
import { loadDocx } from '../../../utils/file-loader';
import docxPlugin from '@hufe921/canvas-editor-plugin-docx';
import excelPlugin from '@hufe921/canvas-editor-plugin-excel';
import floatingToolbarPlugin from '@hufe921/canvas-editor-plugin-floating-toolbar';
import diagramPlugin from '@hufe921/canvas-editor-plugin-diagram';
import casePlugin from '@hufe921/canvas-editor-plugin-case';
import { Dialog } from "./components/dialog/Dialog";
import { formatPrismToken } from "./utils/prism";
import prism from "prismjs";
import {BluePrintApi} from "@/views/ai/agent/x6/api/blue-print-api";
import {md2Html} from "./utils/md";
import {messageBus} from "@/views/ai/miuma/chat/hook";
import {uuid} from "@/components/bpmnProcessDesigner/package/utils";

const root = ref<InstanceType<typeof HTMLDivElement>>();
const editorIns = ref<Editor>();

const loadFile=async ({files}:any)=>{
  console.log("load file===>",files)
  if (files!=undefined&&files as []){
    for (const f of files) {
      try {
        if (f.endsWith('.doc')||f.endsWith(".pdf")){
          const html = await BluePrintApi.doc2Html(f);
          editorIns.value?.command.executeSetValue({
            main:[
              {
                value: html,
              }
            ],
          });
        }
        if (f.endsWith('.docx')){
          const buffer=await loadDocx(f)
          //@ts-ignore
          editorIns.value?.command?.executeImportDocx({arrayBuffer: buffer})
        }
      }catch (e){
        console.error(e)
      }
    }
  }
}
const  doAutoWrite=async (data:any)=>{
  const fileId=data.fileId as string
  const rules=data.rules as string[]
  //console.log("doAutoWrite",fileId,rules)
  let aires=''
  await BluePrintApi.executeByCode('AI_AUTO_WRITING',
    {text:`请按照${rules.join(',')}对文件进行改写,并且输出修改后的文件,对于不知道或者不确定的内容请用[]代替`,fileId},
    (ev)=>{
      try {
        const d=JSON.parse(ev.data)
        if (d.node==='LLM_EXEC'||d.node==='MULTIMODAL'){
          aires+=d.content||''
        }
        //const html = md2Html(aires) as string;
        nextTick(()=>{
          editorIns.value?.command?.executeSetHTML({main:aires});
        })
      }catch (e){
        console.error(e)
      }
    },
    ()=>{
      const html = md2Html(aires) as string;
      console.log("解析后文章",html);
      editorIns.value?.command?.executeSetHTML({main:html});
    },
    undefined,
    (e)=>{
      console.error('sendMsgToAi',e)
      throw e
    }
  )
}

const init = async () => {
  const isApple = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
  // 2. | 撤销 | 重做 | 格式刷 | 清除格式 |
  const undoDom = document.querySelector<HTMLDivElement>('.menu-item__undo')!;
  undoDom.title = `撤销(${isApple ? '⌘' : 'Ctrl'}+Z)`;
  undoDom.onclick = function () {
    console.log('undo');
    editorIns.value?.command.executeUndo();
  };
  const redoDom = document.querySelector<HTMLDivElement>('.menu-item__redo')!;
  redoDom.title = `重做(${isApple ? '⌘' : 'Ctrl'}+Y)`;
  redoDom.onclick = function () {
    console.log('redo');
    editorIns.value?.command.executeRedo();
  };
  const painterDom = document.querySelector<HTMLDivElement>('.menu-item__painter')!;
  let isFirstClick = true;
  let painterTimeout: number;
  painterDom.onclick = function () {
    if (isFirstClick) {
      isFirstClick = false;
      painterTimeout = window.setTimeout(() => {
        console.log('painter-click');
        isFirstClick = true;
        editorIns.value?.command.executePainter({
          isDblclick: false,
        });
      }, 200);
    } else {
      window.clearTimeout(painterTimeout);
    }
  };
  painterDom.ondblclick = function () {
    console.log('painter-dblclick');
    isFirstClick = true;
    window.clearTimeout(painterTimeout);
    editorIns.value?.command.executePainter({
      isDblclick: true,
    });
  };
  document.querySelector<HTMLDivElement>('.menu-item__format')!.onclick = function () {
      console.log('format');
      editorIns.value?.command.executeFormat();
  };
    // 3. | 字体 | 字体变大 | 字体变小 | 加粗 | 斜体 | 下划线 | 删除线 | 上标 | 下标 | 字体颜色 | 背景色 |
  const fontDom = document.querySelector<HTMLDivElement>(".menu-item__font")!;
  const fontSelectDom = fontDom.querySelector<HTMLDivElement>(".select")!;
  const fontOptionDom = fontDom.querySelector<HTMLDivElement>(".options")!;
  fontDom.onclick = function () {
    console.log("font");
    fontOptionDom.classList.toggle("visible");
  };
  fontOptionDom.onclick = function (evt) {
    const li = evt.target as HTMLLIElement;
    editorIns.value?.command.executeFont(li.dataset.family!);
  };

  const sizeSetDom = document.querySelector<HTMLDivElement>(".menu-item__size")!;
  const sizeSelectDom = sizeSetDom.querySelector<HTMLDivElement>(".select")!;
  const sizeOptionDom = sizeSetDom.querySelector<HTMLDivElement>(".options")!;
  sizeSetDom.title = `设置字号`;
  sizeSetDom.onclick = function () {
    console.log("size");
    sizeOptionDom.classList.toggle("visible");
  };
  sizeOptionDom.onclick = function (evt) {
    const li = evt.target as HTMLLIElement;
    editorIns.value?.command.executeSize(Number(li.dataset.size!));
  };
  const sizeAddDom = document.querySelector<HTMLDivElement>(".menu-item__size-add")!;
  sizeAddDom.title = `增大字号(${isApple ? "⌘" : "Ctrl"}+[)`;
  sizeAddDom.onclick = function () {
    console.log("size-add");
    editorIns.value?.command.executeSizeAdd();
  };
  const sizeMinusDom = document.querySelector<HTMLDivElement>(".menu-item__size-minus")!;
  sizeMinusDom.title = `减小字号(${isApple ? "⌘" : "Ctrl"}+])`;
  sizeMinusDom.onclick = function () {
    console.log("size-minus");
    editorIns.value?.command.executeSizeMinus();
  };
  const boldDom = document.querySelector<HTMLDivElement>(".menu-item__bold")!;
  boldDom.title = `加粗(${isApple ? "⌘" : "Ctrl"}+B)`;
  boldDom.onclick = function () {
    console.log("bold");
    editorIns.value?.command.executeBold();
  };

  const italicDom = document.querySelector<HTMLDivElement>(".menu-item__italic")!;
  italicDom.title = `斜体(${isApple ? "⌘" : "Ctrl"}+I)`;
  italicDom.onclick = function () {
    console.log("italic");
    editorIns.value?.command.executeItalic();
  };
  const underlineDom = document.querySelector<HTMLDivElement>(".menu-item__underline")!;
  underlineDom.title = `下划线(${isApple ? "⌘" : "Ctrl"}+U)`;
  const underlineOptionDom = underlineDom.querySelector<HTMLDivElement>(".options")!;
  underlineDom.querySelector<HTMLSpanElement>(".select")!.onclick = function () {
      underlineOptionDom.classList.toggle("visible");
  };
  underlineDom.querySelector<HTMLElement>("i")!.onclick = function () {
    console.log("underline");
    editorIns.value?.command.executeUnderline();
    underlineOptionDom.classList.remove("visible");
  };

  underlineDom.querySelector<HTMLUListElement>("ul")!.onmousedown = function (evt) {
    const li = evt.target as HTMLLIElement;
    const decorationStyle = li.dataset.decorationStyle as TextDecorationStyle | undefined;
    editorIns.value?.command.executeUnderline({
      style: decorationStyle // 保持注释格式一致性
    });
    underlineOptionDom.classList.remove("visible");
  };
  const strikeoutDom = document.querySelector<HTMLDivElement>(".menu-item__strikeout")!;
  strikeoutDom.onclick = function () {
    console.log("strikeout");
    editorIns.value?.command.executeStrikeout();
  };
  const superscriptDom = document.querySelector<HTMLDivElement>(".menu-item__superscript")!;
  superscriptDom.title = `上标(${isApple ? "⌘" : "Ctrl"}+Shift+,)`;
  superscriptDom.onclick = function () {
    console.log("superscript");
    editorIns.value?.command.executeSuperscript();
  };
  const subscriptDom = document.querySelector<HTMLDivElement>(".menu-item__subscript")!;
  subscriptDom.title = `下标(${isApple ? "⌘" : "Ctrl"}+Shift+.)`;
  subscriptDom.onclick = function () {
    console.log("subscript");
    editorIns.value?.command.executeSubscript();
  };
  const colorControlDom = document.querySelector<HTMLInputElement>("#color")!;
  colorControlDom.oninput = function () {
    editorIns.value?.command.executeColor(colorControlDom.value);
  };
  const colorDom = document.querySelector<HTMLDivElement>(".menu-item__color")!;
  const colorSpanDom = colorDom.querySelector("span")!;
  colorDom.onclick = function () {
    console.log("color");
    colorControlDom.click();
  };
  const highlightControlDom = document.querySelector<HTMLInputElement>("#highlight")!;
  highlightControlDom.oninput = function () {
    editorIns.value?.command.executeHighlight(highlightControlDom.value);
  };
  const highlightDom = document.querySelector<HTMLDivElement>(".menu-item__highlight")!;
  const highlightSpanDom = highlightDom.querySelector("span")!;
  highlightDom.onclick = function () {
    console.log("highlight");
    highlightControlDom?.click();
  };
  const titleDom = document.querySelector<HTMLDivElement>(".menu-item__title")!;
  const titleSelectDom = titleDom.querySelector<HTMLDivElement>(".select")!;
  const titleOptionDom = titleDom.querySelector<HTMLDivElement>(".options")!;
  titleOptionDom.querySelectorAll("li").forEach((li, index) => {li.title = `Ctrl+${isApple ? "Option" : "Alt"}+${index}`;});
  titleDom.onclick = function () {
    console.log("title");
    titleOptionDom.classList.toggle("visible");
  };
  titleOptionDom.onclick = function (evt) {
    const li = evt.target as HTMLLIElement;
    const level = li.dataset.level as TitleLevel;
    editorIns.value?.command.executeTitle(level || null);
  };
  const leftDom = document.querySelector<HTMLDivElement>(".menu-item__left")!;
  leftDom.title = `左对齐(${isApple ? "⌘" : "Ctrl"}+L)`;
  leftDom.onclick = function () {
    console.log("left");
    editorIns.value?.command.executeRowFlex(RowFlex.LEFT);
  };
  const centerDom = document.querySelector<HTMLDivElement>(".menu-item__center")!;
  centerDom.title = `居中对齐(${isApple ? "⌘" : "Ctrl"}+E)`;
  centerDom.onclick = function () {
    console.log("center");
    editorIns.value?.command.executeRowFlex(RowFlex.CENTER);
  };
  const rightDom = document.querySelector<HTMLDivElement>(".menu-item__right")!;
  rightDom.title = `右对齐(${isApple ? "⌘" : "Ctrl"}+R)`;
  rightDom.onclick = function () {
    console.log("right");
    editorIns.value?.command.executeRowFlex(RowFlex.RIGHT);
  };

  const alignmentDom = document.querySelector<HTMLDivElement>(
    ".menu-item__alignment"
  )!;
  alignmentDom.title = `两端对齐(${isApple ? "⌘" : "Ctrl"}+J)`;
  alignmentDom.onclick = function () {
    console.log("alignment");
    editorIns.value?.command.executeRowFlex(RowFlex.ALIGNMENT);
  };

  const justifyDom = document.querySelector<HTMLDivElement>(
    ".menu-item__justify"
  )!;
  justifyDom.title = `分散对齐(${isApple ? "⌘" : "Ctrl"}+Shift+J)`;
  justifyDom.onclick = function () {
    console.log("justify");
    editorIns.value?.command.executeRowFlex(RowFlex.JUSTIFY);
  };

  const rowMarginDom = document.querySelector<HTMLDivElement>(
    ".menu-item__row-margin"
  )!;
  const rowOptionDom = rowMarginDom.querySelector<HTMLDivElement>(".options")!;
  rowMarginDom.onclick = function () {
    console.log("row-margin");
    rowOptionDom.classList.toggle("visible");
  };
  rowOptionDom.onclick = function (evt) {
    const li = evt.target as HTMLLIElement;
    editorIns.value?.command.executeRowMargin(Number(li.dataset.rowmargin!));
  };

  const listDom = document.querySelector<HTMLDivElement>(".menu-item__list")!;
  listDom.title = `列表(${isApple ? "⌘" : "Ctrl"}+Shift+U)`;
  const listOptionDom = listDom.querySelector<HTMLDivElement>(".options")!;
  listDom.onclick = function () {
    console.log("list");
    listOptionDom.classList.toggle("visible");
  };
  listOptionDom.onclick = function (evt) {
    const li = evt.target as HTMLLIElement;
    const listType = li.dataset.listType as ListType || null;
    const listStyle = li.dataset.listStyle as ListStyle;
    editorIns.value?.command.executeList(listType, listStyle);
  };


  // 4. | 表格 | 图片 | 超链接 | 分割线 | 水印 | 代码块 | 分隔符 | 控件 | 复选框 | LaTeX | 日期选择器
  const tableDom = document.querySelector<HTMLDivElement>(".menu-item__table")!;
  const tablePanelContainer = document.querySelector<HTMLDivElement>(
    ".menu-item__table__collapse"
  )!;
  const tableClose = document.querySelector<HTMLDivElement>(".table-close")!;
  const tableTitle = document.querySelector<HTMLDivElement>(".table-select")!;
  const tablePanel = document.querySelector<HTMLDivElement>(".table-panel")!;
  // 绘制行列
  const tableCellList: HTMLDivElement[][] = [];
  for (let i = 0; i < 10; i++) {
    const tr = document.createElement("tr");
    tr.classList.add("table-row");
    const trCellList: HTMLDivElement[] = [];
    for (let j = 0; j < 10; j++) {
      const td = document.createElement("td");
      td.classList.add("table-cel");
      tr.append(td);
      trCellList.push(td);
    }
    tablePanel.append(tr);
    tableCellList.push(trCellList);
  }
  let colIndex = 0;
  let rowIndex = 0;
  // 移除所有格选择
  function removeAllTableCellSelect() {
    tableCellList.forEach(tr => {
      tr.forEach(td => td.classList.remove("active"));
    });
  }
  // 设置标题内容
  function setTableTitle(payload: string) {
    tableTitle.innerText = payload;
  }
  // 恢复初始状态
  function recoveryTable() {
    // 还原选择样式、标题、选择行列
    removeAllTableCellSelect();
    setTableTitle("插入");
    colIndex = 0;
    rowIndex = 0;
    // 隐藏panel
    tablePanelContainer.style.display = "none";
  }
  tableDom.onclick = function () {
    console.log("table");
    tablePanelContainer!.style.display = "block";
  };
  tablePanel.onmousemove = function (evt) {
    const celSize = 16;
    const rowMarginTop = 10;
    const celMarginRight = 6;
    const { offsetX, offsetY } = evt;
    // 移除所有选择
    removeAllTableCellSelect();
    colIndex = Math.ceil(offsetX / (celSize + celMarginRight)) || 1;
    rowIndex = Math.ceil(offsetY / (celSize + rowMarginTop)) || 1;
    // 改变选择样式
    tableCellList.forEach((tr, trIndex) => {
      tr.forEach((td, tdIndex) => {
        if (tdIndex < colIndex && trIndex < rowIndex) {
          td.classList.add("active");
        }
      });
    });
    // 改变表格标题
    setTableTitle(`${rowIndex}×${colIndex}`);
  };
  tableClose.onclick = function () {
    recoveryTable();
  };
  tablePanel.onclick = function () {
    // 应用选择
    editorIns.value?.command.executeInsertTable(rowIndex, colIndex);
    recoveryTable();
  };

  const imageDom = document.querySelector<HTMLDivElement>(".menu-item__image")!;
  const imageFileDom = document.querySelector<HTMLInputElement>("#image")!;
  imageDom.onclick = function () {
    imageFileDom.click();
  };
  imageFileDom.onchange = function () {
    const file = imageFileDom.files![0]!;
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = function () {
      // 计算宽高
      const image = new Image();
      const value = fileReader.result as string;
      image.src = value;
      image.onload = function () {
        editorIns.value?.command.executeImage({
          value,
          width: image.width,
          height: image.height
        });
        imageFileDom.value = "";
      };
    };
  };

  const hyperlinkDom = document.querySelector<HTMLDivElement>(
    ".menu-item__hyperlink"
  )!;
  hyperlinkDom.onclick = function () {
    console.log("hyperlink");
    new Dialog({
      title: "超链接",
      data: [
        {
          type: "text",
          label: "文本",
          name: "name",
          required: true,
          placeholder: "请输入文本",
          value: editorIns.value?.command.getRangeText()
        },
        {
          type: "text",
          label: "链接",
          name: "url",
          required: true,
          placeholder: "请输入链接"
        }
      ],
      onConfirm: payload => {
        const name = payload.find(p => p.name === "name")?.value;
        if (!name) return;
        const url = payload.find(p => p.name === "url")?.value;
        if (!url) return;
        editorIns.value?.command.executeHyperlink({
          type: ElementType.HYPERLINK,
          value: "",
          url,
          //@ts-ignore
          valueList: splitText(name).map(n => ({
            value: n,
            size: 16
          }))
        });
      }
    });
  };

  const separatorDom = document.querySelector<HTMLDivElement>(
    ".menu-item__separator"
  )!;
  const separatorOptionDom =
    separatorDom.querySelector<HTMLDivElement>(".options")!;
  separatorDom.onclick = function () {
    console.log("separator");
    separatorOptionDom.classList.toggle("visible");
  };
  separatorOptionDom.onmousedown = function (evt) {
    let payload: number[] = [];
    const li = evt.target as HTMLLIElement;
    const separatorDash = li.dataset.separator?.split(",").map(Number);
    if (separatorDash) {
      const isSingleLine = separatorDash.every(d => d === 0);
      if (!isSingleLine) {
        payload = separatorDash;
      }
    }
    editorIns.value?.command.executeSeparator(payload);
  };

  const pageBreakDom = document.querySelector<HTMLDivElement>(
    ".menu-item__page-break"
  )!;
  pageBreakDom.onclick = function () {
    console.log("pageBreak");
    editorIns.value?.command.executePageBreak();
  };

  const watermarkDom = document.querySelector<HTMLDivElement>(
    ".menu-item__watermark"
  )!;
  const watermarkOptionDom =
    watermarkDom.querySelector<HTMLDivElement>(".options")!;
  watermarkDom.onclick = function () {
    console.log("watermark");
    watermarkOptionDom.classList.toggle("visible");
  };
  watermarkOptionDom.onmousedown = function (evt) {
    const li = evt.target as HTMLLIElement;
    const menu = li.dataset.menu!;
    watermarkOptionDom.classList.toggle("visible");
    if (menu === "add") {
      new Dialog({
        title: "水印",
        data: [
          {
            type: "text",
            label: "内容",
            name: "data",
            required: true,
            placeholder: "请输入内容"
          },
          {
            type: "color",
            label: "颜色",
            name: "color",
            required: true,
            value: "#AEB5C0"
          },
          {
            type: "number",
            label: "字体大小",
            name: "size",
            required: true,
            value: "120"
          }
        ],
        onConfirm: payload => {
          const nullableIndex = payload.findIndex(p => !p.value);
          if (~nullableIndex) return;
          const watermark = payload.reduce(
            (pre, cur) => {
              pre[cur.name] = cur.value;
              return pre;
            },
            {} as any
          );
          editorIns.value?.command.executeAddWatermark({
            data: watermark.data,
            color: watermark.color,
            size: Number(watermark.size)
          });
        }
      });
    } else {
      editorIns.value?.command.executeDeleteWatermark();
    }
  };

  const codeblockDom = document.querySelector<HTMLDivElement>(
    ".menu-item__codeblock"
  )!;
  codeblockDom.onclick = function () {
    console.log("codeblock");
    new Dialog({
      title: "代码块",
      data: [
        {
          type: "textarea",
          name: "codeblock",
          placeholder: "请输入代码",
          width: 500,
          height: 300
        }
      ],
      onConfirm: payload => {
        const codeblock = payload.find(p => p.name === "codeblock")?.value;
        if (!codeblock) return;
        const tokenList = prism.tokenize(codeblock, prism.languages.javascript);
        const formatTokenList = formatPrismToken(tokenList);
        const elementList: IElement[] = [];
        for (let i = 0; i < formatTokenList.length; i++) {
          const formatToken = formatTokenList[i];
          //@ts-ignore
          const tokenStringList = splitText(formatToken.content);
          for (let j = 0; j < tokenStringList.length; j++) {
            const value = tokenStringList[j];
            const element: IElement = {
              //@ts-ignore
              value
            };
            if (formatToken?.color) {
              element.color = formatToken.color;
            }
            if (formatToken?.bold) {
              element.bold = true;
            }
            if (formatToken?.italic) {
              element.italic = true;
            }
            elementList.push(element);
          }
        }
        elementList.unshift({
          value: "\n"
        });
        editorIns.value?.command.executeInsertElementList(elementList);
      }
    });
  };

  const controlDom = document.querySelector<HTMLDivElement>(
    ".menu-item__control"
  )!;
  const controlOptionDom =
    controlDom.querySelector<HTMLDivElement>(".options")!;
  controlDom.onclick = function () {
    console.log("control");
    controlOptionDom.classList.toggle("visible");
  };
  controlOptionDom.onmousedown = function (evt) {
    controlOptionDom.classList.toggle("visible");
    const li = evt.target as HTMLLIElement;
    const type = li.dataset.control as ControlType;
    switch (type) {
      case ControlType.TEXT:
        new Dialog({
          title: "文本控件",
          data: [
            {
              type: "text",
              label: "占位符",
              name: "placeholder",
              required: true,
              placeholder: "请输入占位符"
            },
            {
              type: "text",
              label: "默认值",
              name: "value",
              placeholder: "请输入默认值"
            }
          ],
          onConfirm: payload => {
            const placeholder = payload.find(
              p => p.name === "placeholder"
            )?.value;
            if (!placeholder) return;
            const value = payload.find(p => p.name === "value")?.value || "";
            editorIns.value?.command.executeInsertElementList([
              {
                type: ElementType.CONTROL,
                value: "",
                control: {
                  type,
                  value: value
                    ? [
                        {
                          value
                        }
                      ]
                    : null,
                  placeholder
                }
              }
            ]);
          }
        });
        break;
      case ControlType.SELECT:
        new Dialog({
          title: "列举控件",
          data: [
            {
              type: "text",
              label: "占位符",
              name: "placeholder",
              required: true,
              placeholder: "请输入占位符"
            },
            {
              type: "text",
              label: "默认值",
              name: "code",
              placeholder: "请输入默认值"
            },
            {
              type: "textarea",
              label: "值集",
              name: "valueSets",
              required: true,
              height: 100,
              placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
            }
          ],
          onConfirm: payload => {
            const placeholder = payload.find(
              p => p.name === "placeholder"
            )?.value;
            if (!placeholder) return;
            const valueSets = payload.find(p => p.name === "valueSets")?.value;
            if (!valueSets) return;
            const code = payload.find(p => p.name === "code")?.value;
            editorIns.value?.command.executeInsertElementList([
              {
                type: ElementType.CONTROL,
                value: "",
                control: {
                  type,
                  code,
                  value: null,
                  placeholder,
                  valueSets: JSON.parse(valueSets)
                }
              }
            ]);
          }
        });
        break;
      case ControlType.CHECKBOX:
        new Dialog({
          title: "复选框控件",
          data: [
            {
              type: "text",
              label: "默认值",
              name: "code",
              placeholder: "请输入默认值，多个值以英文逗号分割"
            },
            {
              type: "textarea",
              label: "值集",
              name: "valueSets",
              required: true,
              height: 100,
              placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
            }
          ],
          onConfirm: payload => {
            const valueSets = payload.find(p => p.name === "valueSets")?.value;
            if (!valueSets) return;
            const code = payload.find(p => p.name === "code")?.value;
            editorIns.value?.command.executeInsertElementList([
              {
                type: ElementType.CONTROL,
                value: "",
                control: {
                  type,
                  code,
                  value: null,
                  valueSets: JSON.parse(valueSets)
                }
              }
            ]);
          }
        });
        break;
      case ControlType.RADIO:
        new Dialog({
          title: "单选框控件",
          data: [
            {
              type: "text",
              label: "默认值",
              name: "code",
              placeholder: "请输入默认值"
            },
            {
              type: "textarea",
              label: "值集",
              name: "valueSets",
              required: true,
              height: 100,
              placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
            }
          ],
          onConfirm: payload => {
            const valueSets = payload.find(p => p.name === "valueSets")?.value;
            if (!valueSets) return;
            const code = payload.find(p => p.name === "code")?.value;
            editorIns.value?.command.executeInsertElementList([
              {
                type: ElementType.CONTROL,
                value: "",
                control: {
                  type,
                  code,
                  value: null,
                  valueSets: JSON.parse(valueSets)
                }
              }
            ]);
          }
        });
        break;
      case ControlType.DATE:
        new Dialog({
          title: "日期控件",
          data: [
            {
              type: "text",
              label: "占位符",
              name: "placeholder",
              required: true,
              placeholder: "请输入占位符"
            },
            {
              type: "text",
              label: "默认值",
              name: "value",
              placeholder: "请输入默认值"
            },
            {
              type: "select",
              label: "日期格式",
              name: "dateFormat",
              value: "yyyy-MM-dd hh:mm:ss",
              required: true,
              options: [
                {
                  label: "yyyy-MM-dd hh:mm:ss",
                  value: "yyyy-MM-dd hh:mm:ss"
                },
                {
                  label: "yyyy-MM-dd",
                  value: "yyyy-MM-dd"
                }
              ]
            }
          ],
          onConfirm: payload => {
            const placeholder = payload.find(
              p => p.name === "placeholder"
            )?.value;
            if (!placeholder) return;
            const value = payload.find(p => p.name === "value")?.value || "";
            const dateFormat =
              payload.find(p => p.name === "dateFormat")?.value || "";
            editorIns.value?.command.executeInsertElementList([
              {
                type: ElementType.CONTROL,
                value: "",
                control: {
                  type,
                  dateFormat,
                  value: value
                    ? [
                        {
                          value
                        }
                      ]
                    : null,
                  placeholder
                }
              }
            ]);
          }
        });
        break;
      default:
        break;
    }
  };

  const checkboxDom = document.querySelector<HTMLDivElement>(
    ".menu-item__checkbox"
  )!;
  checkboxDom.onclick = function () {
    console.log("checkbox");
    editorIns.value?.command.executeInsertElementList([
      {
        type: ElementType.CHECKBOX,
        checkbox: {
          value: false
        },
        value: ""
      }
    ]);
  };

  const radioDom = document.querySelector<HTMLDivElement>(".menu-item__radio")!;
  radioDom.onclick = function () {
    console.log("radio");
    editorIns.value?.command.executeInsertElementList([
      {
        type: ElementType.RADIO,
        checkbox: {
          value: false
        },
        value: ""
      }
    ]);
  };

  const latexDom = document.querySelector<HTMLDivElement>(".menu-item__latex")!;
  latexDom.onclick = function () {
    console.log("LaTeX");
    new Dialog({
      title: "LaTeX",
      data: [
        {
          type: "textarea",
          height: 100,
          name: "value",
          placeholder: "请输入LaTeX文本"
        }
      ],
      onConfirm: payload => {
        const value = payload.find(p => p.name === "value")?.value;
        if (!value) return;
        editorIns.value?.command.executeInsertElementList([
          {
            type: ElementType.LATEX,
            value
          }
        ]);
      }
    });
  };

  const dateDom = document.querySelector<HTMLDivElement>(".menu-item__date")!;
  const dateDomOptionDom = dateDom.querySelector<HTMLDivElement>(".options")!;
  dateDom.onclick = function () {
    console.log("date");
    dateDomOptionDom.classList.toggle("visible");
    // 定位调整
    const bodyRect = document.body.getBoundingClientRect();
    const dateDomOptionRect = dateDomOptionDom.getBoundingClientRect();
    if (dateDomOptionRect.left + dateDomOptionRect.width > bodyRect.width) {
      dateDomOptionDom.style.right = "0px";
      dateDomOptionDom.style.left = "unset";
    } else {
      dateDomOptionDom.style.right = "unset";
      dateDomOptionDom.style.left = "0px";
    }
    // 当前日期
    const date = new Date();
    const year = date.getFullYear().toString();
    const month = (date.getMonth() + 1).toString().padStart(2, "0");
    const day = date.getDate().toString().padStart(2, "0");
    const hour = date.getHours().toString().padStart(2, "0");
    const minute = date.getMinutes().toString().padStart(2, "0");
    const second = date.getSeconds().toString().padStart(2, "0");
    const dateString = `${year}-${month}-${day}`;
    const dateTimeString = `${dateString} ${hour}:${minute}:${second}`;
    dateDomOptionDom.querySelector<HTMLLIElement>("li:first-child")!.innerText =
      dateString;
    dateDomOptionDom.querySelector<HTMLLIElement>("li:last-child")!.innerText =
      dateTimeString;
  };
  dateDomOptionDom.onmousedown = function (evt) {
    const li = evt.target as HTMLLIElement;
    const dateFormat = li.dataset.format!;
    dateDomOptionDom.classList.toggle("visible");
    editorIns.value?.command.executeInsertElementList([
      {
        type: ElementType.DATE,
        value: "",
        dateFormat,
        valueList: [
          {
            value: li.innerText.trim()
          }
        ]
      }
    ]);
  };

  const blockDom = document.querySelector<HTMLDivElement>(".menu-item__block")!;
  blockDom.onclick = function () {
    console.log("block");
    new Dialog({
      title: "内容块",
      data: [
        {
          type: "select",
          label: "类型",
          name: "type",
          value: "iframe",
          required: true,
          options: [
            {
              label: "网址",
              value: "iframe"
            },
            {
              label: "视频",
              value: "video"
            }
          ]
        },
        {
          type: "number",
          label: "宽度",
          name: "width",
          placeholder: "请输入宽度（默认页面内宽度）"
        },
        {
          type: "number",
          label: "高度",
          name: "height",
          required: true,
          placeholder: "请输入高度"
        },
        {
          type: "input",
          label: "地址",
          name: "src",
          required: false,
          placeholder: "请输入地址"
        },
        {
          type: "textarea",
          label: "HTML",
          height: 100,
          name: "srcdoc",
          required: false,
          placeholder: "请输入HTML代码（仅网址类型有效）"
        }
      ],
      onConfirm: payload => {
        const type = payload.find(p => p.name === "type")?.value;
        if (!type) return;
        const width = payload.find(p => p.name === "width")?.value;
        const height = payload.find(p => p.name === "height")?.value;
        if (!height) return;
        // 地址或HTML代码至少存在一项
        const src = payload.find(p => p.name === "src")?.value;
        const srcdoc = payload.find(p => p.name === "srcdoc")?.value;
        const block: IBlock = {
          type: type as BlockType
        };
        if (block.type === BlockType.IFRAME) {
          if (!src && !srcdoc) return;
          block.iframeBlock = {
            src,
            srcdoc
          };
        } else if (block.type === BlockType.VIDEO) {
          if (!src) return;
          block.videoBlock = {
            src
          };
        }
        const blockElement: IElement = {
          type: ElementType.BLOCK,
          value: "",
          height: Number(height),
          block
        };
        if (width) {
          blockElement.width = Number(width);
        }
        editorIns.value?.command.executeInsertElementList([blockElement]);
      }
    });
  };
  // 5. | 搜索&替换 | 打印 |
  const searchCollapseDom = document.querySelector<HTMLDivElement>(
    ".menu-item__search__collapse"
  )!;
  const searchInputDom = document.querySelector<HTMLInputElement>(
    ".menu-item__search__collapse__search input"
  )!;
  const replaceInputDom = document.querySelector<HTMLInputElement>(
    ".menu-item__search__collapse__replace input"
  )!;
  const searchDom =
    document.querySelector<HTMLDivElement>(".menu-item__search")!;
  searchDom.title = `搜索与替换(${isApple ? "⌘" : "Ctrl"}+F)`;
  const searchResultDom =
    searchCollapseDom.querySelector<HTMLLabelElement>(".search-result")!;
  function setSearchResult() {
    const result = editorIns.value?.command.getSearchNavigateInfo();
    if (result) {
      const { index, count } = result;
      searchResultDom.innerText = `${index}/${count}`;
    } else {
      searchResultDom.innerText = "";
    }
  }
  searchDom.onclick = function () {
    console.log("search");
    searchCollapseDom.style.display = "block";
    const bodyRect = document.body.getBoundingClientRect();
    const searchRect = searchDom.getBoundingClientRect();
    const searchCollapseRect = searchCollapseDom.getBoundingClientRect();
    if (searchRect.left + searchCollapseRect.width > bodyRect.width) {
      searchCollapseDom.style.right = "0px";
      searchCollapseDom.style.left = "unset";
    } else {
      searchCollapseDom.style.right = "unset";
    }
    searchInputDom.focus();
  };
  searchCollapseDom.querySelector<HTMLSpanElement>("span")!.onclick =
    function () {
      searchCollapseDom.style.display = "none";
      searchInputDom.value = "";
      replaceInputDom.value = "";
      editorIns.value?.command.executeSearch(null);
      setSearchResult();
    };
  searchInputDom.oninput = function () {
    editorIns.value?.command.executeSearch(searchInputDom.value || null);
    setSearchResult();
  };
  searchInputDom.onkeydown = function (evt) {
    if (evt.key === "Enter") {
      editorIns.value?.command.executeSearch(searchInputDom.value || null);
      setSearchResult();
    }
  };
  searchCollapseDom.querySelector<HTMLButtonElement>("button")!.onclick =
    function () {
      const searchValue = searchInputDom.value;
      const replaceValue = replaceInputDom.value;
      if (searchValue && replaceValue && searchValue !== replaceValue) {
        editorIns.value?.command.executeReplace(replaceValue);
      }
    };
  searchCollapseDom.querySelector<HTMLDivElement>(".arrow-left")!.onclick =
    function () {
      editorIns.value?.command.executeSearchNavigatePre();
      setSearchResult();
    };
  searchCollapseDom.querySelector<HTMLDivElement>(".arrow-right")!.onclick =
    function () {
      editorIns.value?.command.executeSearchNavigateNext();
      setSearchResult();
    };

  const printDom = document.querySelector<HTMLDivElement>(".menu-item__print")!;
  printDom.title = `打印(${isApple ? "⌘" : "Ctrl"}+P)`;
  printDom.onclick = function () {
    console.log("print");
    editorIns.value?.command.executePrint();
  };
  const saveDom = document.querySelector<HTMLDivElement>(".menu-item__save")!;
  saveDom.title = `保存文档`;
  saveDom.onclick = function () {
    console.log("save");
    const id = uuid();
    //@ts-ignore
    editorIns.value?.command.executeExportDocx({fileName:id+'LawSeek'})
  };
};
onMounted(() => {
  if (root.value) {
    editorIns.value = new Editor(
      root.value,
      {
        header: [
          {
            value: '',
            rowFlex: RowFlex.CENTER,
          },
        ],
        main: [
          {
            value: '',
          },
        ],
        footer: [
          {
            value: 'LawSeek',
            size: 12,
          },
        ],
      },
      {},
    );
    editorIns.value.use(floatingToolbarPlugin);
    editorIns.value.use(docxPlugin);
    editorIns.value.use(excelPlugin);
    editorIns.value.use(diagramPlugin);
    editorIns.value.use(casePlugin);
    //挂载时初始化
    init();
    messageBus.on('DoAutoWrite',doAutoWrite)
    messageBus.on('DocEditorLoadFile',loadFile)
  }
});
onUnmounted(()=>{
  messageBus.off('DoAutoWrite',doAutoWrite)
  messageBus.off('DocEditorLoadFile',loadFile)
})
</script>

<template>
  <div class="CanvasEditor">
    <MenuBar/>
    <div class="CanvasEditor__wrap">
      <div ref="root" class="doc-editor"></div>
    </div>
  </div>
</template>

<style lang="scss">
.CanvasEditor{
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .CanvasEditor__wrap{
    flex: 1;
    overflow: auto;
    .doc-editor {
      width: 100%;
      & > div {
        margin: auto;
      }
    }
  }
}
</style>
